package cn.ccbom.bom.interview.core.design_pattern.singleton.normal;

import cn.ccbom.bom.interview.core.design_pattern.singleton.LocalClient;
import cn.hutool.core.thread.ThreadUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.log4j.Log4j2;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@UtilityClass
@Log4j2
public class LocalClientUtil {
    public static LocalClient singleton;

    public LocalClient singleton() {
        if (singleton == null) {
            synchronized (LocalClient.class) {
                if (singleton == null) {
                    singleton = new LocalClient("1", "本地客户端");
                }
            }
        }
        return singleton;
    }

    /**
     * threadA: step2: 未完成
     * threadB: step1: 正在执行
     */
    public LocalClient singleton001() {
        if (singleton == null) { //step1 <-- threadA
            ThreadUtil.sleep(1000);//添加重复
            log.info("线程创建了实例对象: {} {}", Thread.currentThread().getName(),singleton.toString());
            return  new LocalClient("1", "本地客户端"); //step2 <-- threadB
        }
        return singleton;
    }

    public void singletonRun001() {
        int maxThread = 20;
        int totalSize = 20;
        ExecutorService executorService = Executors.newFixedThreadPool(maxThread);
        CountDownLatch countDownLatch = new CountDownLatch(totalSize);
        List<LocalClient> container = Collections.synchronizedList(new LinkedList<>());

        for (int i = 0; i < totalSize; i++) {
            executorService.execute(() -> {
                try {
                    LocalClient localClient = singleton001();
                    container.add(localClient);//不是线程安全的
                } catch (Exception ex) {
                    log.error(ex.getMessage());
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        try {
            countDownLatch.await();
            log.info("对象一致性: {}", container.stream().allMatch(e -> e == container.get(0)));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //16:58:33.719 [pool-1-thread-3] INFO cn.ccbom.bom.interview.core.design_pattern.singleton.normal.LocalClientUtil - 线程创建了实例对象: pool-1-thread-3
        //16:58:33.719 [pool-1-thread-1] INFO cn.ccbom.bom.interview.core.design_pattern.singleton.normal.LocalClientUtil - 线程创建了实例对象: pool-1-thread-1
        //16:58:33.719 [pool-1-thread-2] INFO cn.ccbom.bom.interview.core.design_pattern.singleton.normal.LocalClientUtil - 线程创建了实例对象: pool-1-thread-2
        //16:58:33.726 [main] INFO cn.ccbom.bom.interview.core.design_pattern.singleton.normal.LocalClientUtil - 对象一致性: true
        LocalClientUtil.singletonRun001();
    }
}
